//
// Created by Yun on 2025/2/26.
//

#include "time_slice_os.h"

/**
 * @brief 时间片轮转操作系统状态
 */
enum TimeSliceOS_State
{
    TIME_SLICE_OS_IDLE = 0U,
    TIME_SLICE_OS_RUNNING,
    TIME_SLICE_OS_BUSY,
};


/* 任务节点结构体 */
typedef struct Task_Node{
    struct Task_Node* pNext;
    Task_Callback_TypeDef pfnCallback;
    void* pArgs;
    uint8_t u8Pri;
    uint8_t uReserved;                 /*!< 保留字段 */
    uint16_t uReserved1;                 /*!< 保留字段 */
} Task_Node_TypeDef;

typedef struct Task_Head_Node{
    Task_Node_TypeDef* pNext;
    TimeSliceOsCfg_TypeDef u8Id;
} Task_Head_Node_TypeDef;

typedef struct TimeSliceOS_Controller
{
    uint32_t u32TimeSliceOSTick;
    Task_Head_Node_TypeDef stTaskHead[TASK_HEAD_LEN];
    Task_Node_TypeDef stTaskPool[TASK_POOL_MAX_NUM];
    uint8_t u8TaskPoolIndex;
    uint8_t u8TimeSliceOSState;
}TimeSliceOS_Controller_TypeDef;


/**
 * @brief 初始化时间片轮转操作系统
 * @return 1:初始化成功 0:初始化失败
 */
uint8_t TimeSliceOS_Init(void* pTSOSController)
{
    TimeSliceOS_Controller_TypeDef* pstTSOSController = (TimeSliceOS_Controller_TypeDef*)pTSOSController;
    pstTSOSController->u8TimeSliceOSState = TIME_SLICE_OS_IDLE;
    pstTSOSController->u32TimeSliceOSTick = 1;
    pstTSOSController->u8TaskPoolIndex = 0;

    /* 初始化事件头链表 */
    for(uint8_t i = 0; i < TASK_HEAD_LEN; i++) {
        pstTSOSController->stTaskHead[i].u8Id = i + 1;
        pstTSOSController->stTaskHead[i].pNext = NULL;
    }

    /* 初始化事件池 */
    for(uint8_t i = 0; i < TASK_POOL_MAX_NUM; i++) {
        pstTSOSController->stTaskPool[i].u8Pri = 0;
        pstTSOSController->stTaskPool[i].pfnCallback = NULL;
        pstTSOSController->stTaskPool[i].pNext = NULL;
    }

    return 1;
}

uint8_t TimeSliceOS_Register(void* pTSOSController,uint8_t u8TimeSliceId, uint8_t u8TaskPri, Task_Callback_TypeDef pfnCallback, void* pArgs)
{
    TimeSliceOS_Controller_TypeDef* pstTSOSController = (TimeSliceOS_Controller_TypeDef*)pTSOSController;
    /* 参数检查 */
    if(pstTSOSController->u8TaskPoolIndex >= TASK_POOL_MAX_NUM || u8TimeSliceId < 1) return 0;

    /* 申请事件节点 */
    Task_Node_TypeDef* pstTaskNode = &(pstTSOSController->stTaskPool)[pstTSOSController->u8TaskPoolIndex++];
    pstTaskNode->u8Pri = u8TaskPri;
    pstTaskNode->pfnCallback = pfnCallback;
    pstTaskNode->pArgs = pArgs;
    pstTaskNode->pNext = NULL;

    /* 插入到对应事件链表 */
    Task_Head_Node_TypeDef* pstEvtHeadNode = &(pstTSOSController->stTaskHead[u8TimeSliceId - 1]);

    /* 空链表 */
    Task_Node_TypeDef* pstOldNode = pstEvtHeadNode->pNext;
    if(pstOldNode == NULL)
    {
        pstEvtHeadNode->pNext = pstTaskNode;
        return 1;
    }
    /* 只有一个节点  */
    Task_Node_TypeDef* pstNewNode = pstOldNode->pNext;
    if(pstNewNode == NULL)
    {
        if(pstOldNode->u8Pri >= pstTaskNode->u8Pri)
        {
            pstOldNode->pNext = pstTaskNode;
            return 1;
        }
        else
        {
            pstTaskNode->pNext = pstOldNode;
            pstEvtHeadNode->pNext = pstTaskNode;
            return 1;
        }
    }
    /* 多节点遍历链表 */
    while(pstNewNode != NULL)
    {
        /* 最小优先级，插入末尾 */
        if(pstNewNode->u8Pri >= pstTaskNode->u8Pri)
        {
            pstNewNode->pNext = pstTaskNode;
            return 1;
        }
            /* 高优先级，插入头部 */
        else if(pstTaskNode->u8Pri > pstOldNode->u8Pri)
        {
            pstTaskNode->pNext = pstOldNode;
            pstEvtHeadNode->pNext = pstTaskNode;
            return 1;
        }
            /* 相同优先级，插入中间 */
        else if(pstTaskNode->u8Pri > pstNewNode->u8Pri &&
                pstTaskNode->u8Pri <= pstOldNode->u8Pri)
        {
            pstTaskNode->pNext = pstNewNode;
            pstOldNode->pNext = pstTaskNode;
            return 1;
        }
        pstOldNode = pstNewNode;
        pstNewNode = pstNewNode->pNext;
    }
    return 1;
}

void TimeSliceOS_Run(void* pTSOSController)
{
    TimeSliceOS_Controller_TypeDef* pstTSOSController = (TimeSliceOS_Controller_TypeDef*)pTSOSController;

    if(pstTSOSController->u8TimeSliceOSState == TIME_SLICE_OS_BUSY ||
        pstTSOSController->u32TimeSliceOSTick == TIME_SLICE_NONE) return;

    pstTSOSController->u8TimeSliceOSState = TIME_SLICE_OS_RUNNING;
    pstTSOSController->u32TimeSliceOSTick++;

    if(pstTSOSController->u32TimeSliceOSTick > TimeSliceOS_TimeCfg[TASK_HEAD_LEN - 1])
        pstTSOSController->u32TimeSliceOSTick = 1;

    pstTSOSController->u8TimeSliceOSState = TIME_SLICE_OS_BUSY;

    for(uint8_t i = 0; i < TASK_HEAD_LEN; i++)
    {
        Task_Head_Node_TypeDef* pstTaskHeadNode = &(pstTSOSController->stTaskHead[i]);
        uint8_t u8Id = pstTaskHeadNode->u8Id;
        Task_Node_TypeDef* pstTaskNode = pstTaskHeadNode->pNext;
        while(pstTaskNode != NULL)
        {
            if(u8Id > TIME_SLICE_NONE && pstTaskNode->pfnCallback != NULL)
            {
                if(TimeSliceOS_TimeCfg[u8Id - 1] != 0)
                {
                    if(pstTSOSController->u32TimeSliceOSTick %
                        TimeSliceOS_TimeCfg[u8Id - 1] == 0)
                    {
                        pstTaskNode->pfnCallback(pstTaskNode->pArgs);
                    }
                }
            }
            pstTaskNode = pstTaskNode->pNext;
        }
    }

    pstTSOSController->u8TimeSliceOSState = TIME_SLICE_OS_IDLE;

}
